#!/usr/bin/env python
# coding: utf-8

# In[1]:


import pandas as pd

# market = "hair_dryer"
market = "microwave"
# market = "pacifier"

inputexcel = pd.read_excel("../Problem_C_Data/" + market + '.xlsx', market)
# 评论的个数
num_review = len(list(inputexcel['star_rating']))
print(num_review)

xlsxxlsx = '../Problem_C_Data/good_contain.xls'
good_words = pd.read_excel(xlsxxlsx, 'Sheet1')
good_words = good_words.key.values.tolist()
xlsxxlsx = '../Problem_C_Data/bad_contain.xls'
bad_words = pd.read_excel(xlsxxlsx, 'Sheet1')
bad_words = bad_words.key.values.tolist()
# print(bad_words[1:5])
# good_words[3]


writer = pd.ExcelWriter("./2e_output/apriori star rating descriptors 2e akapriori select first contain "+market+".xlsx",)


# In[2]:


import re
def load_selected_star(inputexcel,star_rating_12345):
    # 一行代表一个评论，一行第一个元素是star_rating
    output = []
    star_rating_list = list(inputexcel[inputexcel['star_rating']==star_rating_12345]['star_rating'])
    review_headline_list = list(inputexcel[inputexcel['star_rating']==star_rating_12345]['review_headline'])
    review_body_list = list(inputexcel[inputexcel['star_rating']==star_rating_12345]['review_body'])

    for ii in range(len(star_rating_list)):
    #     用正则表达式替换掉所有不是英文字母和空格的字符变成空格
        review_headline = re.sub('[^a-zA-Z\s]', ' ', str(review_headline_list[ii]))
        review_body = re.sub('[^a-zA-Z\s]', ' ', str(review_body_list[ii]))
    #     避免review_headline最后一个单词和review_body第一个单词挨在一起，中间加个空格
        review = review_headline + ' ' + review_body
    #     小写 以空格分词
        reviews = review.lower().split(' ')
        onereview = []
    #     提取出评论文本中的每个单词
        for review_word in reviews:
    #         如果在好词列表中，那么就加进该评论对应的的词表
            if review_word in good_words:
                onereview.append(review_word)
    #         如果在坏词列表中，那么就加进该评论对应的的词表
            if review_word in bad_words:
                onereview.append(review_word)
    #     将该评论的词表添加到所有评论词表末尾
        output.append(list(str(star_rating_list[ii]))+onereview)
    return output


# In[3]:


# 选取出所有 star_rating_12345 的评论
from akapriori import apriori

for star_rating_12345 in range(1, 6):
    output = load_selected_star(inputexcel, star_rating_12345)

    # print(len(output))
    # for r in output[1:6]:
    #         print(r)
    # print()

    '''
    https://github.com/aknd/akapriori
    https://blog.csdn.net/qq_35515661/article/details/87391328

    transactions 待处理数据 列表套多元组的格式 [(),()...]

    support 最小支持度 P(AB) 
    Support(A→B)= P(A∩B) 

    confidence 最小置信度  P(B/A)  条件概率  
    P(AB)/P(A)
    Confidence(A→B)=P(B|A)=P(A∩B)/P(A)

    lift 判断的阈值 1/P(A)  先验概率的倒数  
    P(AB)/(P(A)P(B)) Lift=1时表示A和B独立。
    Lift(A→B)=Confidence(A→B)/Support(B)=P(B|A)/P(B)

    minlen maxlen  候选集最小长度 最大长度

    '''

    rules = apriori(output, support=0.05, confidence=0.3,
                    lift=0, minlen=0, maxlen=5)
    # 根据参数进行排序输出 排序优先级： lift 降序, confidence 降序, support 降序
    rules_sorted = sorted(rules, key=lambda x: (
        x[4], x[3], x[2]), reverse=True)
    '''
    rules_sorted[0]  frozenset
    rules_sorted[1]  frozenset
    rules_sorted[2]  support 最小支持度 P(AB)
    rules_sorted[3]  confidence 最小置信度  P(B/A)  条件概率
    rules_sorted[4]  lift 判断的阈值 1/P(A)  先验概率的倒数
    '''

    # 查找所有 含有 star_rating_12345 的 rules_sorted
    rules_sorted_contain_star_rating_12345 = []
    for rules_sort in rules_sorted:
        if (str(star_rating_12345) in rules_sort[0]) or (str(star_rating_12345) in rules_sort[1]):
            rules_sorted_contain_star_rating_12345.append(rules_sort)

    # list → dataframe
    rules_sorted_contain_star_rating_12345 = pd.DataFrame(
        rules_sorted_contain_star_rating_12345, columns=[
            'frozensetA', 'frozensetB', 'support', 'confidence', 'lift'])

    print(rules_sorted_contain_star_rating_12345.head())
    print()

    rules_sorted_contain_star_rating_12345.to_excel(
        writer, sheet_name=str(star_rating_12345), index=False)


writer.save()




